引用
引用是给一个变量起别名,引用没有自己独立的空间,引用要与它所引用的变量共享空间
。引用在定义的时候要进行初始化,引用一经初始化,不能重新指向其他变量
const 引用
const引用是指向const对象的引用
const int ival = 1024;
const int& refVal = ival; //ok:both reference and object are const
int &ref2 = ival; //error:nonconst reference to a const object 防止对引用的更改,更改了const对象
int ival = 1024;
const int& refVal = ival; // ok
const引用,类型转换的情况
double val3 = 3.14;
const int& ref4 = val3; //等价于 int tmp = val3; const int& ref4 = temp;
int val4 = vals3; //erro:duoble不能转为int
引用作参数传递
值传递,对形参值的改变不能对实参产生影响。引用作为参数对形参的任何操作都能改变相应的实参的数据。
引用作参数时,函数的实参与形参在内存中共用存储单元
,因此形参的变化会使实参同时变化
函数返回引用
函数返回引用的一个主要目的是可以将函数放在赋值运算符的左边
int a[] = {0,1,2,3,4};
int &index(int i)
{
return a[i];
}
int main()
{
index(3) = 100; //函数放在赋值运算符的左边,引用在函数返回的时候初始化
}
函数返回引用需要注意的地方是不能返回对局部变量的引用
#include <iostream>
using namespace std;
int &add(int a, int b)
{
int sum;
sum = a + b;
return sum;
}
int main(void)
{
int n = add(3, 4);
int &n2 = add(5, 6);
cout << "n2=" << n2 << endl;
cout << "n=" << n << endl;
cout << "n2=" << n2 << endl;
return 0;
}
程序结果输出
n2=11
n=7
n2=1474313670
返回局部变量的引用导致的后果。函数返回的是局部变量sum的引用,而n2 本身又是引用,即引用着原来sum拥有的那块区域,第一次打印没有出错是因为本来写在sum 区域上的值11尚未被覆盖,而再运行两条打印语句后再次打印,很可能原来属于sum的区域变dirty了,被覆盖了其他不确定的值,每次打印都不会是一个定值
n本身是个变量,函数返回时立马保存了sum所属区域的值
,局部变量在函数栈上释放,但本来区域的值第一时间还是原来的值,但经过程序运行,堆栈内存区域重用,一般就被覆盖了
。
引用与指针区别
- 引用访问一个变量是
直接访问
,而指针是间接访问
。 - 引用是一个变量的别名,本身
不单独分配
自己的内存空间,而指针有自己的内存空间
。 - 引用一经初始化
不能再引用
其它变量,而指针可以
。c++建议尽可能使用引用,不得已时使用指针
数组引用与指针引用
#include<iostream>
using namespace std;
void func1(char s[10]) // char *s
{
cout<<"func1"<<endl;
cout<<sizeof(s)<<endl;
cout<<s[1]<<endl;
s[1] = 'B';
cout<<s[1]<<endl;
}
void func2(char (&ss)[100]) // 数组引用
{
cout<<"func2"<<endl;
cout<<sizeof(ss)<<endl;
cout<<ss[1]<<endl;
char * f2 = ss;
f2[1] = 'D';
cout<<f2[1]<<endl;
}
void func3(char * const & sss)// 指针引用
{
cout<<"func3"<<endl;
cout<<sizeof(sss)<<endl;
cout<<sss[1]<<endl;
char * f3 = sss;
f3[1] = 'F';
cout<<f3[1]<<endl;
}
int main(void)
{
char s[10] = {'a', 'b'};
char ss[100] = {'c', 'd'};
char sss[1000] = {'e', 'f'};
cout<<"main fun"<<endl;
cout<<sizeof(s)<<endl;
func1(s);
func2(ss);
// func2(sss); error
func3(sss);
return 0;
}
值传递\引用传递\指针传递
值传递 实参初始化形参,分配空间,将实参内容拷贝到形参
引用传递 实参初始化形参时,不分配空间
指针传递 本质是值传递
,实参初始化形参,分配指针本身的空间
。如果要修改指针的地址
,单纯的用指针传递是不行的。需要采用**,*&的方式传递